package com.example.clientend.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

/**
 * 接收到MQTT消息后，处理主控端指令的工具类
 */
@Component
@Slf4j
public class MqttHandler {
    @Autowired
    BatFileHandler batFileHandler;
    @Autowired
    StringMatcher stringMatcher;
    @Autowired
    InfoGetter infoGetter;
    @Autowired
    RestTemplate restTemplate;
    
    // 主控端接收发起远控操作的回应的接口
    @Value("${url.installServiceUrl}")
    private String installServiceUrl;
    // 主控端接收结束远控操作的回应的接口
    @Value("${url.uninstallServiceUrl}")
    private String uninstallServiceUrl;

    /**
     * 根据instruction判断需要注册远控服务还是删除远控服务
     * @param instruction
     */
    public void handlerMqttInstruction(String instruction){
        if (instruction.equals("install")){
            this.installService();
        }
        if (instruction.equals("uninstall")){
            this.uninstallService();
        }
        if (instruction.equals("clearLog")){
            // 发起远控失败时主控端发送此命令清空被控端会话信息输出日志，防止被控端日志不为空而显示正在被控但是时间上无法被控的情况
            batFileHandler.clearLog();
        }
    }

    /**
     * 调用向日葵SDK注册远控服务，并将生成的远控会话信息通过公网IP接口返回给主控端
     */
    private void installService(){
        log.info("接收到主控端的远控请求，开始注册远控服务并生成对话信息。");
        try {
            // 注册服务前先执行服务卸载，确保当前系统未注册服务
            batFileHandler.uninstallService();
            // 线程等待1000ms，等待远控服务注销完成并输出信息到log文件中
            Thread.sleep(1000);
            // 清空会话信息输出日志
            batFileHandler.clearLog();
            // 注册服务
            batFileHandler.installService();
            log.info("远控服务注册成功！");
            // 设置计时器
            int timeCounter = 0;
            while (1==1){
                Thread.sleep(100);
                timeCounter += 100;
                // 读取会话信息输出日志中的内容，截取出远控需要的address和cid
                JSONObject sessionInfo = stringMatcher.readInfo();
                // 判断是否截取成功(即判断远控服务是否注册成功)
                if (stringMatcher.infoCheck(sessionInfo)){
                    // 若注册成功，则读取本机deviceClientId添加至远控会话信息sessionInfo中
                    JSONObject deviceInfo = infoGetter.getDeviceInfo();
                    String deviceClientId = (String) deviceInfo.get("deviceClientId");
                    sessionInfo.put("deviceClientId",deviceClientId);
                    // 添加msg便于主控端进行校验
                    sessionInfo.put("msg","连接发起成功！");
                    // 调用主控端接口发送给主控端
                    String result = restTemplate.postForObject(installServiceUrl, sessionInfo, String.class);
                    log.info("成功生成远控会话信息并推送至主控端！远控会话信息：" + sessionInfo);
                    break;
                }
                // 若超时则报错
                if (timeCounter > 3000){
                    log.info("远控会话信息生成失败！");
                    throw new RuntimeException("远控会话信息生成失败！");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 调用向日葵SDK解除远控服务
     */
    private void uninstallService(){
        log.info("主控端远控结束，进行远控服务注销。");
        try {
            // 调用SDK解除远控服务
            batFileHandler.uninstallService();
            log.info("远控服务注销成功！");
            // 获取本机deviceClientId并生成处理结果uninstallResponse返回给主控端
            JSONObject deviceInfo = infoGetter.getDeviceInfo();
            String deviceClientId = (String) deviceInfo.get("deviceClientId");
            JSONObject uninstallResponse = new JSONObject();
            uninstallResponse.put("deviceClientId",deviceClientId);
            uninstallResponse.put("msg",deviceClientId + "的远控服务注销成功！");
            // 调用主控端接口发送给主控端
            String result = restTemplate.postForObject(uninstallServiceUrl, uninstallResponse, String.class);
            // 线程等待1000ms，等待远控服务注销完成并输出信息到会话信息输出日志中
            Thread.sleep(1000);
            // 清空日志
            batFileHandler.clearLog();
        }catch (Exception e){
            e.printStackTrace();
            log.info("远控服务注销失败！");
        }
    }
}
